package com.congee02.autocrud.util;

import org.springframework.util.Assert;

import javax.persistence.Id;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public final class EntityUtils {

    private EntityUtils() {}

    /**
     * 寻找到一个类的 Id 字段
     * @param clazz 类的字码对象
     * @return 字段对象
     */
    public static Field getEntityIdField(Class clazz) {
        Field idFieldLoop = null;
        final Field[] clazzFields = clazz.getDeclaredFields();
        for (Field field : clazzFields) {
            if (field.isAnnotationPresent(Id.class)) {
                Assert.isTrue(field.getType().equals(Long.class), "The id field must be type of Long.");
                idFieldLoop = field;
                break;
            }
        }
        Assert.notNull(idFieldLoop, "The entity must have an id field.");
        return idFieldLoop;
    }

    /**
     * 获取一个类 Id 字段的 Getter 方法
     * @param clazz 类的字码对象
     * @return Id Getter 方法对象
     */
    private static String GETTER_PREFIX = "get";
    public static Method getEntityIdGetterMethod(Class clazz) {
        return idMethodName(GETTER_PREFIX, clazz);
    }

    /**
     * 获取一个类 Id 字段的 Setter 方法
     * @param clazz 类的字码对象
     * @return Id Setter 方法对象
     */
    private static String SETTER_PREFIX = "set";
    public static Method getEntityIdSetterMethod(Class clazz) {
        return idMethodName(SETTER_PREFIX, clazz, Long.class);
    }

    private static Method idMethodName(String prefix, Class clazz, Class... args) {
        final Field field = getEntityIdField(clazz);
        final String name = field.getName();
        String firstChar = name.substring(0, 1).toUpperCase();
        String idGetterName = prefix + firstChar + name.substring(1);

        Method tryMethod;
        try {
            tryMethod = clazz.getMethod(idGetterName, args);
        } catch (NoSuchMethodException e) {
            tryMethod = null;
            e.printStackTrace();
        }
        return tryMethod;
    }

}
